package com.panda.framework.netty.async;

import Jubo.JuLiao.IM.Wx.Proto.AcceptFriendAddRequestTask.AcceptFriendAddRequestTaskMessage;
import Jubo.JuLiao.IM.Wx.Proto.AgreeJoinChatRoomTask.AgreeJoinChatRoomTaskMessage;
import Jubo.JuLiao.IM.Wx.Proto.FriendAddNotice.FriendMessage;
import Jubo.JuLiao.IM.Wx.Proto.FriendAddReqeustNotice.FriendAddReqeustNoticeMessage;
import Jubo.JuLiao.IM.Wx.Proto.FriendPushNotice.FriendPushNoticeMessage;
import Jubo.JuLiao.IM.Wx.Proto.FriendTalkNotice.FriendTalkNoticeMessage;
import Jubo.JuLiao.IM.Wx.Proto.SendLuckyMoneyTask.SendLuckyMoneyTaskMessage;
import Jubo.JuLiao.IM.Wx.Proto.TakeLuckyMoneyTask.TakeLuckyMoneyTaskMessage;
import Jubo.JuLiao.IM.Wx.Proto.TalkToFriendTask.TalkToFriendTaskMessage;
import Jubo.JuLiao.IM.Wx.Proto.TransportMessageOuterClass.EnumContentType;
import Jubo.JuLiao.IM.Wx.Proto.TransportMessageOuterClass.EnumErrorCode;
import Jubo.JuLiao.IM.Wx.Proto.TransportMessageOuterClass.EnumMsgType;
import Jubo.JuLiao.IM.Wx.Proto.TransportMessageOuterClass.TransportMessage;
import Jubo.JuLiao.IM.Wx.Proto.WeChatOfflineNotice.WeChatOfflineNoticeMessage;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.protobuf.Message;
import com.panda.business.domain.*;
import com.panda.business.domain.AccountInfo;
import com.panda.business.service.*;
import com.panda.framework.common.AutoType;
import com.panda.framework.netty.common.Constant;
import com.panda.framework.netty.utils.ByteStringToString;
import com.panda.framework.netty.utils.MessageUtil;
import com.panda.framework.netty.utils.MsgIdBuilder;
import com.panda.framework.netty.utils.NettyConnectionUtil;
import com.panda.framework.util.JsonUtils;
import io.netty.channel.ChannelHandlerContext;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
@EnableAsync
public class AsyncTaskService {
	private final Logger log = LoggerFactory.getLogger(getClass());
	@Autowired
	private AccountService accountService;

	@Autowired
	private WeChatMessageService weChatMessageService;

	@Autowired
	private WeChatContactService weChatContactService;

	@Autowired
	private WeChatAccountService weChatAccountService;

	@Autowired
	private SysAutoSettingService sysAutoSettingService;

	
	/**
	 * 自动抢红包、自动收账
	 * @param ctx
	 * @param type
	 * @param req
	 * @param accessToken
	 * @param msgId
	 */
	private static void takeLuckyMoney(ChannelHandlerContext ctx,Integer type,FriendTalkNoticeMessage req,String accessToken,long msgId){
		String content = ByteStringToString.bytesToString(req.getContent(), "utf-8");
		if(type == AutoType.AUTOTYPE_LUCKMONEY){//红包有个人红包和群红包
			if(!JsonUtils.isJson(content)){//群红包处理
				int index =  content.indexOf("{");
				if(index>0){
					content= content.substring(index,content.length());
				}
			}
		}
		JSONObject json = JSON.parseObject(content);
		String key = null;
		if (null != json) {
			key = json.get("Key").toString();
		}
		if (!StringUtils.isBlank(key)) {
			TakeLuckyMoneyTaskMessage.Builder bd = TakeLuckyMoneyTaskMessage.newBuilder();
			bd.setWeChatId(req.getWeChatId());
			bd.setFriendId(req.getFriendId());
			bd.setMsgSvrId(req.getMsgSvrId());
			bd.setMsgKey(key);
			bd.setTaskId(MsgIdBuilder.getId());
			TakeLuckyMoneyTaskMessage resp = bd.build();
			MessageUtil.sendMsg(ctx, EnumMsgType.TakeLuckyMoneyTask,accessToken,msgId,resp);
		}
		
	}
	
	/**
	 * 拦截手机端消息做一下自动功能
	 * 
	 * @param wechatId
	 * @param type
	 * @param req
	 */
	@Async
	public void msgAopTask(ChannelHandlerContext ctx, FriendTalkNoticeMessage req,String accessToken,long msgId) {

		try {
			log.info(LocalDateTime.now() + " msgAopTask 对应的线程名: " + Thread.currentThread().getName());
			if (req.getContentType().equals(EnumContentType.LuckyMoney)) {// 红包消息
				SysAutoSetting sys = sysAutoSettingService.findSettingByWcIdAutoType(req.getWeChatId(),AutoType.AUTOTYPE_LUCKMONEY);
				if (null != sys) {
					if (null != req.getContent()) {
						takeLuckyMoney(ctx, AutoType.AUTOTYPE_LUCKMONEY, req, accessToken, msgId);
					}
				}
			}
			
			if (req.getContentType().equals(EnumContentType.MoneyTrans)) {// 转账消息
				SysAutoSetting sys = sysAutoSettingService.findSettingByWcIdAutoType(req.getWeChatId(),AutoType.AUTOTYPE_MONEYTRANS);
				if (null != sys) {
					if (null != req.getContent()) {
						takeLuckyMoney(ctx, AutoType.AUTOTYPE_MONEYTRANS, req, accessToken, msgId);
					}
				}
			}
			 
			if (req.getContentType().equals(EnumContentType.Link)) {// 链接消息，判断是否是群邀请链接
				String content = ByteStringToString.bytesToString(req.getContent(), "utf-8");
				if(!JsonUtils.isJson(content)){
					int index =  content.indexOf("{");
					if(index>0){
						content= content.substring(index,content.length());
					}
				}
				JSONObject json = JSON.parseObject(content);
				Object obj = json.get("Title");
				if (null != obj) {
					String title = obj.toString();
					if (title.contains("邀请你加入群聊")) {
						SysAutoSetting sys = sysAutoSettingService.findSettingByWcIdAutoType(req.getWeChatId(),AutoType.AUTOTYPE_GROUPINVITATION);
						if (null != sys) {
							String talker = req.getFriendId();
							AgreeJoinChatRoomTaskMessage.Builder bd = AgreeJoinChatRoomTaskMessage.newBuilder();
							bd.setWeChatId(req.getWeChatId());
							bd.setMsgSvrId(req.getMsgSvrId());
							bd.setTalker(talker);
							bd.setTaskId(MsgIdBuilder.getId());
							bd.setMsgContent(content);
							AgreeJoinChatRoomTaskMessage resp = bd.build();
							MessageUtil.sendMsg(ctx, EnumMsgType.AgreeJoinChatRoomTask,accessToken,msgId, resp);
						}
					}
				}
			}

		} catch (Throwable e) {
			e.printStackTrace();
		}

	}
	
	/**
	 * 拦截手机端好友请求消息
	 * 
	 * @param wechatId
	 * @param type
	 * @param req
	 */
	@Async
	public void msgAopTaskFriendAdd(ChannelHandlerContext ctx, FriendAddReqeustNoticeMessage req,String accessToken,long msgId) {
//		try {
//			log.info(LocalDateTime.now() + " msgAopTask 对应的线程名: " + Thread.currentThread().getName());
//			SysAutoSetting sys = sysAutoSettingService.findSettingByWcIdAutoType(req.getWeChatId(),AutoType.AUTOTYPE_FRIENDREQEST);
//			if (null != sys) {
//				AcceptFriendAddRequestTaskMessage.Builder  bd = AcceptFriendAddRequestTaskMessage.newBuilder();
//				bd.setWeChatId(req.getWeChatId());
//				bd.setFriendId(req.getFriendId());
//				bd.setFriendNick(req.getFriendNick());
//				bd.setOperationValue(1);//默认接受请求
//				AcceptFriendAddRequestTaskMessage resp = bd.build();
//				MessageUtil.sendMsg(ctx, EnumMsgType.AcceptFriendAddRequestTask, accessToken, msgId, resp);
//			}
//		} catch (Throwable e) {
//			e.printStackTrace();
//		}

	}

	
	

	/**
	 * 转发消息给pc客户端
	 * 
	 * @param wechatId
	 * @param type
	 * @param req
	 */
	@Async
	public void msgSend2pc(String wechatId, EnumMsgType type, Message req) {

		try {
			log.info(LocalDateTime.now() + " msgSend2pc 对应的线程名: " + Thread.currentThread().getName());
			// 先从缓存取，如果取不到再用sql取
			List<WeChatAccountInfo> accountInfoList = Constant.accountInfoList;
			if (null == accountInfoList || accountInfoList.size() == 0) {
				// 刷新缓存
				accountInfoList = weChatAccountService.refreshCache();
			}

			String account = null;
			if (null != accountInfoList && accountInfoList.size() > 0) {
				for (int i = 0; i < accountInfoList.size(); i++) {
					WeChatAccountInfo ainfo = accountInfoList.get(i);
					if (null != ainfo && ainfo.getWechatid().equals(wechatId)) {
						account = ainfo.getAccount();
						break;
					}
				}
			} else {
				AccountInfo accInfo = accountService.findAccountInfoByWeChatId(wechatId);
				if (null != accInfo) {
					account = accInfo.getAccount();
					// 刷新缓存
					weChatAccountService.refreshCache();
				}
			}

			if (!StringUtils.isBlank(account)) {
				// 转发给pc端
				ChannelHandlerContext chx = NettyConnectionUtil.getClientChannelHandlerContextByUserId(account);
				if (null != chx) {
					MessageUtil.sendJsonMsg(chx, type, NettyConnectionUtil.getNettyId(chx), null, req);
				}
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}

	}

	/**
	 * 转发消息给手机客户端
	 * 
	 * @param ctx
	 * @param wechatId
	 * @param type
	 * @param vo
	 * @param req
	 */
	@Async
	public void msgSend2Phone(ChannelHandlerContext ctx, String wechatId, EnumMsgType type, TransportMessage vo,Message req) {

		try {
			log.info(LocalDateTime.now() + " msgSend2Phone 对应的线程名: " + Thread.currentThread().getName());

			ChannelHandlerContext chx = NettyConnectionUtil.getClientChannelHandlerContextByUserId(wechatId);
			if (null != chx) {
				// 转发给手机端
				MessageUtil.sendMsg(chx, type, vo.getAccessToken(), null, req);
				// 告诉发送方 消息已经收到
				MessageUtil.sendJsonMsg(ctx, EnumMsgType.MsgReceivedAck, vo.getAccessToken(), vo.getId(), null);
			} else {
				if (type == EnumMsgType.TalkToFriendTask) {
					// 做个保护，如果微信不在线，则通知pc端，下线其微信
					WeChatAccountInfo account = weChatAccountService.findWeChatAccountInfoByWeChatId(wechatId);
					account.setIsonline(1);// 下线
					weChatAccountService.updateOnline(account);
					// 通知pc端下线其微信
					WeChatOfflineNoticeMessage resp = WeChatOfflineNoticeMessage.newBuilder().setWeChatId(wechatId)
							.build();
					MessageUtil.sendJsonMsg(ctx, EnumMsgType.WeChatOfflineNotice, NettyConnectionUtil.getNettyId(ctx),
							null, resp);
				} else {
					// 对方不在线
					MessageUtil.sendJsonErrMsg(ctx, EnumErrorCode.TargetNotOnline,
							Constant.createErrorMsg(wechatId, Constant.ERROR_MSG_NOTONLINE));
				}
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	/**
	 * 保存通讯录录列表数据
	 * 
	 * @param req
	 * @param account
	 */
	@Async
	public void friendListSave(FriendPushNoticeMessage req, WeChatAccountInfo account) {
		log.info(LocalDateTime.now() + " friendListSave 对应的线程名: " + Thread.currentThread().getName());

		List<FriendMessage> friendList = req.getFriendsList();
		if (null != friendList && friendList.size() > 0) {
			String wechatId = req.getWeChatId();
			for (int i = 0; i < friendList.size(); i++) {
				FriendMessage friend = friendList.get(i);
				if (null != friend) {
					try {
						WeChatContactInfo contactinfo = weChatContactService.findContactinfoByfriendid(account.getCid(),
								wechatId, friend.getFriendId());
						if (null != contactinfo) {
							setContActinfo(contactinfo, friend);
							weChatContactService.update(contactinfo);
						} else {
							contactinfo = new WeChatContactInfo();
							setContActinfo(contactinfo, friend);
							contactinfo.setCid(account.getCid());
							contactinfo.setWechatid(req.getWeChatId());
							contactinfo.setFriendid(friend.getFriendId());
							weChatContactService.insert(contactinfo);
						}
					} catch (Throwable e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	private static void setContActinfo(WeChatContactInfo contactinfo, FriendMessage friend) {
		contactinfo.setFriend_wechatno(friend.getFriendNo());
		contactinfo.setNickname(friend.getFriendNick());
		contactinfo.setGender(friend.getGenderValue());
		contactinfo.setAvatar(friend.getAvatar());
		contactinfo.setRemark(friend.getRemark());
		contactinfo.setCountry(friend.getCountry());
		contactinfo.setProvince(friend.getProvince());
		contactinfo.setCity(friend.getCity());
		contactinfo.setState(0);
	}

	/**
	 * 修改msgserverid
	 */
	@Async
	public void updateMsgServerId(String weChatId, String friendId, long msgId, long msgServerId) {
		try {
			log.info(LocalDateTime.now() + " updateMsgServerId 对应的线程名: " + Thread.currentThread().getName());
			WeChatMessageInfo msgInfo = weChatMessageService.queryWeChatMessageInfoByMsgServerId(weChatId, friendId,String.valueOf(msgId));
			if (null != msgInfo) {
				msgInfo.setMsgSvrId(String.valueOf(msgServerId));
				weChatMessageService.update(msgInfo);
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	/**
	 * 保存消息
	 * 
	 * @param weChatMessageService
	 * @param account
	 * @param req
	 */
	@Async
	public void saveMessage(WeChatAccountInfo account, FriendTalkNoticeMessage req) {
		try {
			log.info(LocalDateTime.now() + " saveMessage 对应的线程名: " + Thread.currentThread().getName());

			WeChatMessageInfo info = new WeChatMessageInfo();
			String content = ByteStringToString.bytesToString(req.getContent(), "utf-8");
			info.setCid(account.getCid());
			info.setWechatId(req.getWeChatId());
			info.setFriendId(req.getFriendId());
			info.setMsgSvrId(String.valueOf(req.getMsgSvrId()));
			info.setIsSend("false");// 收到的消息
			info.setContentType(req.getContentTypeValue());
			info.setContent(content);// base64了 需要解码存储
			weChatMessageService.insert(info);
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	/**
	 * 保存发送消息
	 * 
	 * @param req
	 */
	@Async
	public void savePcMessage(TalkToFriendTaskMessage req) {
		log.info(LocalDateTime.now() + " savePcMessage 对应的线程名: " + Thread.currentThread().getName());
		WeChatAccountInfo account = weChatAccountService.findWeChatAccountInfoByWeChatId(req.getWeChatId());
		if (null != account) {
			try {
				WeChatMessageInfo info = new WeChatMessageInfo();
				String content = ByteStringToString.bytesToString(req.getContent(), "utf-8");
				info.setCid(account.getCid());
				info.setWechatId(req.getWeChatId());
				info.setFriendId(req.getFriendId());
				info.setMsgSvrId(String.valueOf(req.getMsgId()));
				info.setIsSend("true");// 发送
				info.setContentType(req.getContentTypeValue());
				info.setContent(content);// base64了 需要解码存储
				weChatMessageService.insert(info);
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 保存红包消息
	 * 
	 * @param req
	 * @param contentJsonStr
	 */
	@Async
	public void saveLuckyMoneyMessage(SendLuckyMoneyTaskMessage req, String contentJsonStr) {
		log.info(LocalDateTime.now() + " saveLuckyMoneyMessage 对应的线程名: " + Thread.currentThread().getName());
		WeChatAccountInfo wechat = weChatAccountService.findWeChatAccountInfoByWeChatId(req.getWeChatId());
		if (null != wechat) {
			try {
				WeChatMessageInfo info = new WeChatMessageInfo();
				String content = contentJsonStr;
				info.setCid(wechat.getCid());
				info.setWechatId(req.getWeChatId());
				info.setFriendId(req.getFriendId());
				info.setMsgSvrId(String.valueOf(req.getTaskId()));
				info.setIsSend("true");// 发送
				info.setContentType(11);
				info.setContent(content);
				weChatMessageService.insert(info);
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}
	}

}
